package qc.module.ehs.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import qc.common.core.exception.QCPromptException;
import qc.common.core.unify.QCUnifyReturnValue;
import qc.common.core.utils.IdentifierUtil;
import qc.module.ehs.dto.templatehazard.TplHazardCategoryDto;
import qc.module.ehs.entity.EhsTplHazardcategory;
import qc.module.ehs.entity.EhsTplHazarddb;
import qc.module.ehs.entity.EhsTplHazarditem;
import qc.module.ehs.entity.EhsTplHazardproject;
import qc.module.ehs.mapper.EhsTplHazardcategoryMapper;
import qc.module.ehs.repository.EhsTplHazardcategoryRepository;
import qc.module.ehs.repository.EhsTplHazarddbRepository;
import qc.module.ehs.repository.EhsTplHazarditemRepository;
import qc.module.ehs.repository.EhsTplHazardprojectRepository;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 危险源类别接口Service
 *
 * @author QuCheng Tech
 * @create 2024/5/22
 */
@Service
public class EhsTplHazardcategoryService {
    
    private EhsTplHazardcategoryRepository repository;

    @Autowired
    public void setRepository(EhsTplHazardcategoryRepository repository) {
        this.repository = repository;
    }

    @Autowired
    private EhsTplHazarddbRepository hazarddbRepository;

    @Autowired
    private EhsTplHazardprojectRepository hazardprojectRepository;
    
    @Autowired
    private EhsTplHazarditemRepository hazarditemRepository;

    /**
     * 获取指定危险源导则库的类别
     *
     * @param hdbcd 危险源导则库代码
     * @return List<TplHazardCategoryDto>
     * @author QuCheng Tech
     * @since 2024/5/23
     */
    public List<TplHazardCategoryDto> getDBCategories(String hdbcd) throws QCPromptException {
        if (StringUtils.isBlank(hdbcd)) throw new QCPromptException("危险源导则库代码不能为空");

        LambdaQueryWrapper<EhsTplHazardcategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EhsTplHazardcategory::getHdbcd,hdbcd);
        wrapper.orderByAsc(EhsTplHazardcategory::getOdr);
        List<EhsTplHazardcategory> ens = repository.selectList(wrapper);
        
        if (CollectionUtils.isNotEmpty(ens)){
            return EhsTplHazardcategoryMapper.MAPPER.toDtoList(ens);
        }
        return null;
    }

    /**
     * 获取指定危险源类别
     *
     * @param id 危险源类别代码
     * @return TplHazardCategoryDto
     * @author QuCheng Tech
     * @since 2024/5/24
     */
    public TplHazardCategoryDto getCategory(String id) throws QCPromptException {
        if (StringUtils.isBlank(id)) throw new QCPromptException("危险源类别代码不能为空");
        
        EhsTplHazardcategory en = repository.selectById(id);
        if (Objects.nonNull(en)){
            return EhsTplHazardcategoryMapper.MAPPER.toDto(en);
        }
        return null;
    }

    /**
     * 新增指定危险源类别
     *
     * @param dto 危险源类别信息
     * @param isImportDB 是否为导入时添加
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/5/24
     */
    public String addCategory(TplHazardCategoryDto dto,boolean isImportDB){
        //1.危险源类别信息判空
        if (dto == null) return QCUnifyReturnValue.Warn("危险源类别信息不能为空");
        //if (StringUtils.isBlank(dto.getHcatcd())) return QCUnifyReturnValue.Warn("危险源类别代码不能为空");
        if (StringUtils.isBlank(dto.getHcatnm())) return QCUnifyReturnValue.Warn("危险源类别名称不能为空");
        if (StringUtils.isBlank(dto.getHdbcd())) return QCUnifyReturnValue.Warn("危险源导则库代码不能为空");
        //if (dto.getTags() == null) return QCUnifyReturnValue.Warn("标签不能为空");
        
        //2.判断危险源类别代码是否存在，存在则提示
        //if (hcatcdIsExist(dto.getHcatcd())) return QCUnifyReturnValue.Warn("危险源类别代码已经存在");
        
        //3.判断危险源导则库代码是否存在，不存在则提示
        EhsTplHazarddb db = hazarddbRepository.selectById(dto.getHdbcd());
        if (Objects.isNull(db)) return QCUnifyReturnValue.Warn("危险源导则库代码不存在");
        
        //4.dto -> entity
        EhsTplHazardcategory en = EhsTplHazardcategoryMapper.MAPPER.toEntity(dto);
        if (!isImportDB) en.setHcatcd(IdentifierUtil.randomUUID());
        
        //5.保存数据
        if (repository.insert(en) < 0x1){
            return QCUnifyReturnValue.Warn("保存失败");
        }
        return QCUnifyReturnValue.Success();
    }

    /**
     * 修改指定危险源类别
     *
     * @param dto 危险源类别信息
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/5/24
     */
    public String updateCategory(TplHazardCategoryDto dto){
        //1.危险源类别信息判空
        if (dto == null) return QCUnifyReturnValue.Warn("危险源类别信息不能为空");
        if (StringUtils.isBlank(dto.getHcatcd())) return QCUnifyReturnValue.Warn("危险源类别代码不能为空");
        if (StringUtils.isBlank(dto.getHcatnm())) return QCUnifyReturnValue.Warn("危险源类别名称不能为空");
        if (StringUtils.isBlank(dto.getHdbcd())) return QCUnifyReturnValue.Warn("危险源导则库代码不能为空");
        //if (dto.getTags() == null) return QCUnifyReturnValue.Warn("标签不能为空");

        //2.判断危险源类别代码是否存在，不存在则提示
        if (!hcatcdIsExist(dto.getHcatcd())) return QCUnifyReturnValue.Warn("危险源类别代码不存在");

        //3.判断危险源导则库代码是否存在，不存在则提示
        EhsTplHazarddb db = hazarddbRepository.selectById(dto.getHdbcd());
        if (Objects.isNull(db)) return QCUnifyReturnValue.Warn("危险源导则库代码不存在");

        //4.dto -> entity
        EhsTplHazardcategory en = EhsTplHazardcategoryMapper.MAPPER.toEntity(dto);
        
        //5.更新数据
        repository.updateById(en);
        return QCUnifyReturnValue.Success();
    }
    
    /**
     * 删除指定危险源类别
     * 同时删除该类别下的项目和清单
     *
     * @param id 危险源类别代码
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/5/24
     */
    public String deleteCategory(String id){
        if (StringUtils.isBlank(id)) return QCUnifyReturnValue.Warn("危险源类别代码不能为空");
        
        //获取该类别下的项目代码集合
        LambdaQueryWrapper<EhsTplHazardproject> projectWrapper = new LambdaQueryWrapper<>();
        projectWrapper.eq(EhsTplHazardproject::getHcatcd,id);
        List<EhsTplHazardproject> projects = hazardprojectRepository.selectList(projectWrapper);
        if (CollectionUtils.isNotEmpty(projects)){
            List<String> projectIds = projects.stream().map(EhsTplHazardproject::getHpjtcd).collect(Collectors.toList());
            //删除以上项目代码集合的清单
            if (CollectionUtils.isNotEmpty(projectIds)){
                LambdaQueryWrapper<EhsTplHazarditem> itemWrapper = new LambdaQueryWrapper<>();
                itemWrapper.in(EhsTplHazarditem::getHpjtcd,projectIds);
                hazarditemRepository.delete(itemWrapper);

                //删除该类别下的项目
                hazardprojectRepository.deleteBatchIds(projectIds);
            }
        }
        
        //删除类别
        repository.deleteById(id);
        return QCUnifyReturnValue.Success();
    }
    

    /**
     * 判断指定危险源项目代码是否存在
     *
     * @param id 危险源项目代码
     * @return true表示存在，false表示不存在
     * @author QuCheng Tech
     * @since 2024/5/23
     */
    public boolean hcatcdIsExist(String id){
        EhsTplHazardcategory en = repository.selectById(id);
        if (Objects.nonNull(en)){
            return true;
        }
        return false;
    }

    /**
     * 获取类别中的导则库代码集合
     * 
     * @param hcatcds 类别代码集合
     * @param tags 标签
     * @return List<String>
     * @author QuCheng Tech
     * @since 2024/5/24
     */
    public List<String> getHdbcds(List<String> hcatcds,Integer tags){
        LambdaQueryWrapper<EhsTplHazardcategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(EhsTplHazardcategory::getHdbcd);
        if (CollectionUtils.isNotEmpty(hcatcds)){
            wrapper.in(EhsTplHazardcategory::getHcatcd,hcatcds);
        }
        if (tags != null){
            wrapper.eq(EhsTplHazardcategory::getTags,tags);
        }
        List<EhsTplHazardcategory> ens = repository.selectList(wrapper);
        if (CollectionUtils.isNotEmpty(ens)){
            List<String> hdbcds = ens.stream().map(EhsTplHazardcategory::getHdbcd).collect(Collectors.toList());
            return hdbcds.stream().distinct().collect(Collectors.toList());
        }
        return null;
    }
}
